use actix_web::{body::BoxBody, http::header::ContentType, HttpRequest, HttpResponse, Responder};
use serde::Serialize;
use crate::error::AppErr;
use super::req::Cbor;

pub const HEAD_RESP_TYPE: &'static str = "RESP-TYPE";
pub const HEAD_TYPE_OK: &'static str = "OK";
pub const HEAD_TYPE_ERR: &'static str = "ERR";

impl<T: Serialize> Responder for Cbor<T> {

    type Body = BoxBody;

    fn respond_to(self, _req: &HttpRequest) -> HttpResponse {
        let body = serde_cbor::to_vec(&self.0).unwrap();
        HttpResponse::Ok()
            .content_type(ContentType::octet_stream())
            .insert_header((HEAD_RESP_TYPE, HEAD_TYPE_OK))
            .body(body)
    }
}

impl Responder for Void {

    type Body = BoxBody;

    fn respond_to(self, _req: &HttpRequest) -> HttpResponse {
        HttpResponse::Ok()
            .content_type(ContentType::octet_stream())
            .insert_header((HEAD_RESP_TYPE, HEAD_TYPE_OK))
            .finish()
    }
}

pub struct Void;

pub type CborBody<T> = Result<Cbor<T>, AppErr>;
pub type CborVoid = Result<Void, AppErr>;

pub fn new_cbor<T>(value: T) -> CborBody<T> {
    Ok(Cbor(value))
}

pub fn new_void() -> CborVoid {
    Ok(Void)
}





